package main

import (
	"github.com/gorilla/mux"
	"net/http"
	"time"
	"log"
	"flag"
	"os"
	"os/signal"
	"context"
)

func main() {

	var wait time.Duration
	flag.DurationVar(&wait, "graceful-timeout", time.Second * 15, "服务器优雅地等待现有连接完成的持续时间,例如15秒或1m")
	flag.Parse()

	r := mux.NewRouter()

	//静态资源支持
	var dir string
	flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
	flag.Parse()
	// This will serve files under http://localhost:8000/static/<filename>
	r.PathPrefix("/mnt/").Handler(http.StripPrefix("/mnt/", http.FileServer(http.Dir(dir))))


	//路由
	r.HandleFunc("/hello", hello).Methods("GET","POST")
	r.HandleFunc("/bye", bye)
	//引入中间件
	r.Use(loggingMiddleware)

	srv := &http.Server{
		Addr:         "127.0.0.1:8080",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
		IdleTimeout:  time.Second * 60,
		Handler: r, //传入gorilla/mux的实例.
	}
	//在goroutine中运行我们的服务器，这样它就不会阻塞
	go func() {
		if err := srv.ListenAndServe(); err != nil {
			log.Println(err)
		}
	}()

	c := make(chan os.Signal, 1)
	//当通过SIGINT (Ctrl+C)退出时，我们将接受优雅的关闭
	//不会捕获SIGKILL、SIGQUIT或SIGTERM (Ctrl+/)
	signal.Notify(c, os.Interrupt)

	//直到我们收到信号为止
	<-c

	//设定一个等待的截止时间
	ctx, cancel := context.WithTimeout(context.Background(), wait)
	defer cancel()
	//如果没有连接，则不会阻塞，否则将等到超时截止日期。
	srv.Shutdown(ctx)
	//您可以选择运行srv。如果您的应用程序应该基于上下文取消等待其他服务完成，则在goroutine中关闭并阻塞<-ctx.Done()
	log.Println("shutting down")
	os.Exit(0)
}

func hello(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("hello"))
}

func bye(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("bye"))
}

//中间件,每个请求耗时
func loggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Do stuff here
		//log.Println(r.RequestURI)
		//// Call the next handler, which can be another middleware in the chain, or the final handler.
		//next.ServeHTTP(w, r)

		timeStart := time.Now()
		// next handler
		next.ServeHTTP(w, r)

		timeElapsed := time.Since(timeStart)
		log.Println(timeElapsed)

	})
}
